package com.tqjc.system.core.socket;

import com.tqjc.system.common.constant.GlobalConstant;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.SimpleFormatter;

/**
 * @author 86195
 * @version 1.0
 * @description MES发送报文处理器
 * @date 2023/10/12 10:48
 */
@Slf4j
public class MESSocketSendOperator {

    private static final ThreadLocal<Socket> threadConnect = new ThreadLocal();

    private static Socket client;

    private static OutputStream outStream = null;

    private static InputStream inStream = null;

    private static Thread keepThread = new Thread(new KeepThread());

    public static Lock lock = new ReentrantLock();

    //TODO:生产设置地址和端口未定
    private static String host = "192.168.215.149";
    private static int port = 9090;


    // 连接以及重新连接
    public static void connect() {
        try {
            lock.lock();
            disconnect();
            client = threadConnect.get();
            if (client == null) {
                client = new Socket(host, port);
                threadConnect.set(client);
                log.info("========连接开始！========");
            } else if (client.isClosed()) {
                client = new Socket(host, port);
                threadConnect.set(client);
                log.info("========连接开始！========");
            } else {
                client = threadConnect.get();
                log.info("当前已建立连接，请勿重复建立");
            }
            outStream = client.getOutputStream();
            inStream = client.getInputStream();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
            keepThread = new Thread(new KeepThread());
            //recvThread = new Thread(new RecvThread());
            keepThread.start();
            //recvThread.start();
//            if (!reconnectThread.isAlive()) {
//                reconnectThread.start();
//            }

        }

    }

    // 断开连接
    public static void disconnect() {
        try {
            lock.lock();
            client = threadConnect.get();
            if (outStream != null) {
                outStream.close();

                outStream.flush();
            }
            if (inStream != null) {
                inStream.close();
            }

            if (client != null) {
                if (!client.isClosed()) {
                    client.close();
                    threadConnect.set(client);
                }
            }
//            if (recvThread != null) {
//                recvThread.interrupt();
//            }
            if (keepThread != null) {
                keepThread.interrupt();
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }


    // 发送消息
    public static void sendMsg(String msg) {
        try {
            log.info("发送信息至MES:{}", new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date()));
            byte[] bytes = msg.getBytes("UTF-8");
            outStream.write(bytes);
            outStream.flush();
        } catch (IOException e) {
            log.error("发送信息至MES出现异常",e);
            e.printStackTrace();
        }
    }


    public static void sendKeepMsg(String msg) throws IOException {
        byte[] bytes = msg.getBytes("UTF-8");
        outStream.write(bytes);
        outStream.flush();
    }

    private static class KeepThread implements Runnable {
        @Override
        public void run() {
            while (true) {
                try {

                    Thread.sleep(60*1000);
                    lock.lock();
                    Date date = new Date();
                    String dateStr = new SimpleDateFormat("yyyyMMddHHmmss").format(date);
                    log.info("MES通道发送心跳数据包：{}" , new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(date));
                    sendKeepMsg(assembleMsg(dateStr));
                } catch (Exception e) {
                    connect();
                    log.error("MES通道发送心跳数据包出现异常",e);
                    throw new RuntimeException(e);
                } finally {
                    lock.unlock();
                }
            }


        }
    }


    public static String assembleMsg(String dateStr){
        StringBuffer sb = new StringBuffer();
        StringBuffer msgBody =  sb.append(GlobalConstant.MSG_NO_HEARTBEAT).append(dateStr).append(GlobalConstant.MSG_CAR_CODE)
                .append(GlobalConstant.MSG_MES_CODE).append(GlobalConstant.MSG_TRANSFER_CODE_C).append(GlobalConstant.MSG_END_CODE);
        String s = msgBody.toString();
        int length = s.length() + 4;
        DecimalFormat sf = new DecimalFormat("0000");
        String lengthFormat = sf.format(length);
        s = lengthFormat + msgBody;
        return s;

    }

}
